package com.shopnight.interceptors;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.shopnight.entity.ShopAddress;
import com.shopnight.entity.ShopGoods;
import com.shopnight.entity.ShopIndent;
import com.shopnight.mapper.ShopAddressMapper;
import com.shopnight.mapper.ShopGoodsMapper;
import com.shopnight.mapper.ShopIndentMapper;
import com.shopnight.mapper.UserMapper;
import com.shopnight.result.ApiResult;
import com.shopnight.service.impl.CarServiceImpl;
import com.shopnight.utils.AppcationContextUtil;
import com.shopnight.utils.UserContext;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

public class ScriptInterceptors implements HandlerInterceptor {



    public String userId;
    private  UserMapper userMapper = (UserMapper) AppcationContextUtil.getBean("userMapper");
    private StringRedisTemplate stringRedisTemplate = (StringRedisTemplate) AppcationContextUtil.getBean("stringRedisTemplate");
    private ShopIndentMapper shopIndentMapper = (ShopIndentMapper) AppcationContextUtil.getBean("shopIndentMapper");
    private ShopGoodsMapper shopGoodsMapper = (ShopGoodsMapper) AppcationContextUtil.getBean("shopGoodsMapper");
    private ShopAddressMapper shopAddressMapper = (ShopAddressMapper) AppcationContextUtil.getBean("shopAddressMapper");
    private CarServiceImpl carServiceImpl = (CarServiceImpl) AppcationContextUtil.getBean("carServiceImpl");


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
         userId = UserContext.getEndUserId();

        if (userMapper.selectById( userId ) == null ){
            ResMsg(response,"禁用脚本code1 !!!"); return false;
        }

        String requestURI = request.getRequestURI();

//脚本攻击添加订单接口时
        if (requestURI.equals("/api/token/addIndent")) {
           return addIndentFrequently(response,8,3);

        }

//脚本攻击添加购物车接口时
        if (requestURI.equals("/api/token/addToCart")){
            return addToCartFrequently(response,5,7);
        }

//脚本攻击添加用户地址接口
        if (requestURI.equals("/api/token/addOrUpdateAddress")){
            return addOrUpdateAddressFrequently(response,5,4);
        }



        return true;
    }



    public void ResMsg(HttpServletResponse response,String msg) throws IOException {
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().print(JSON.toJSONString(ApiResult.fail(msg)) );
    }


   public Boolean addIndentFrequently(HttpServletResponse response,Integer time, Integer timeNum) throws IOException {

       //判定是否为脚本
       if (stringRedisTemplate.hasKey("addIndent:" + userId)) {
           String number = stringRedisTemplate.opsForValue().get("addIndent:" + userId);

           if (Integer.valueOf(number) >= timeNum) {
               //删除用户所有信息
               deleteUserAllData();
               ResMsg(response, "禁用脚本code2 !!!");
               return false;
           }
           //次数加一
           stringRedisTemplate.opsForValue().increment("addIndent:" + userId, 1);
       } else {
           stringRedisTemplate.opsForValue().set("addIndent:" + userId, "1", time, TimeUnit.SECONDS);
       }

       return true;
   }



    private Boolean addToCartFrequently(HttpServletResponse response, Integer time, Integer timeNum) throws IOException {
        //判定是否为脚本
        if (stringRedisTemplate.hasKey("addToCart:" + userId)) {
            String number = stringRedisTemplate.opsForValue().get("addToCart:" + userId);

            if (Integer.valueOf(number) >= timeNum) {
                //删除用户所有信息
                deleteUserAllData();

                ResMsg(response, "禁用脚本code3 !!!");
                return false;
            }
            //次数加一
            stringRedisTemplate.opsForValue().increment("addToCart:" + userId, 1);
        } else {
            stringRedisTemplate.opsForValue().set("addToCart:" + userId, "1", time, TimeUnit.SECONDS);
        }
        return true;
    }

    private Boolean addOrUpdateAddressFrequently(HttpServletResponse response,Integer time, Integer timeNum) throws IOException {
        //判定是否为脚本
        if (stringRedisTemplate.hasKey("addOrUpdateAddress:" + userId)) {
            String number = stringRedisTemplate.opsForValue().get("addOrUpdateAddress:" + userId);

            if (Integer.valueOf(number) >= timeNum) {
                //删除用户所有信息
                deleteUserAllData();
                ResMsg(response, "禁用脚本code4 !!!");
                return false;
            }
            //次数加一
            stringRedisTemplate.opsForValue().increment("addOrUpdateAddress:" + userId, 1);
        } else {
            stringRedisTemplate.opsForValue().set("addOrUpdateAddress:" + userId, "1", time, TimeUnit.SECONDS);
        }

        return true;
    }


    public  void  deleteUserAllData(){


        userMapper.deleteById(userId);

        //订单数据
        List<Long> collect = shopIndentMapper.selectList(
                new LambdaQueryWrapper<ShopIndent>()
                        .eq(ShopIndent::getUserId, userId)
        ).stream().map(item -> item.getIndentId()).collect(Collectors.toList());

        shopIndentMapper.delete(
                new LambdaQueryWrapper<ShopIndent>()
                        .in(ShopIndent::getIndentId, collect)
        );
        shopGoodsMapper.delete(
                new LambdaQueryWrapper<ShopGoods>()
                        .in(ShopGoods::getIndentId, collect)
        );

       //购物车数据
        carServiceImpl.userIdByDelete(userId);



        //地址数据
        shopAddressMapper.delete(
                new LambdaQueryWrapper<ShopAddress>()
                        .eq(ShopAddress::getUserId,userId)
        );






    }

}
